package cn.cnlee.arch.util;

import androidx.annotation.NonNull;

import java.lang.reflect.ParameterizedType;

/**
 * Class类相关工具类
 */
public class ClassUtil {

    /**
     * 获取object类范型参数的实例
     *
     * @param object
     * @param i      范型参数的位置
     * @param <T>
     * @return
     */
    public static <T> T getTypeNewInstance(Object object, int i) {
        if (object != null) {
            try {
                return ((Class<T>) ((ParameterizedType) (object.getClass().getGenericSuperclass()))
                        .getActualTypeArguments()[i]).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassCastException e) {
                e.printStackTrace();
            }

        }
        return null;
    }

    /**
     * 实例化
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T getNewInstance(Class cls) {
        if (cls != null) {
            try {
                return ((Class<T>) cls).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassCastException e) {
                e.printStackTrace();
            }

        }
        return null;
    }

    /**
     * 获取object类范型参数的Class
     *
     * @param object
     * @param i      范型参数的位置
     * @param <T>
     * @return
     */
    public static <T> T getTypeInstance(Object object, int i) {
        if (object != null) {
            return (T) ((ParameterizedType) object.getClass().getGenericSuperclass())
                    .getActualTypeArguments()[i];
        }
        return null;

    }


    /**
     * 检查reference参数不能为空
     *
     * @param reference
     * @param <T>
     * @return
     */
    public static @NonNull
    <T> T checkNotNull(T reference) {
        if (reference == null) {
            throw new NullPointerException();
        }
        return reference;
    }

}
